<template>
  <div>
    <div 
      ref="slider" 
      class="slider" 
    >
      <div 
        :style="{width}" 
        class="process"/>
      <div 
        v-if="showSteps" 
        class="node-wrap" >
        <div 
          v-for="(item, i) in nodeList"
          :key="i" 
        >
          <span 
            :style="{left: item.left}" 
            class="step" /> 
          <span 
            :style="{left: item.left}" 
            class="value">
            {{ item.value }} {{ unit }}</span>
        </div>
      </div>

      <div 
        ref="thunkformM" 
        :style="{left}" 
        class="thunk formForM"
        @touchstart="start"
        @touchmove="move"
        @touchend="end"
      >
        <div class="block"/>
        <div 
          v-if="showTips" 
          class="tips">
          <span>{{ scale*100 }}</span>
          <i class="fas fa-caret-down" />
        </div>
      </div>
      <div 
        ref="thunkformPC" 
        :style="{left}" 
        class="thunk formForPC"
        @mousedown="start"
      >
        <div class="block formForPC"/>
        <div 
          v-if="showTips" 
          class="tips formForPC">
          <span>{{ scale*100 }}</span>
          <i class="fas fa-caret-down" />
        </div>
      </div>
    </div>

  </div>
</template>
<script>
export default {
  props: {
    min: {
      type: [Number],
      default: 1
    },
    max: {
      type: [Number],
      default: 1
    },
    value: {
      type: [Number],
      default: 1
    },
    step: {
      type: [Number],
      default: 1
    },
    showTips: {
      type: [Boolean],
      default: false
    },
    showSteps: {
      type: [Boolean],
      default: false
    },
    unit: {
      type: [String],
      default: ''
    },
    name: {
      type: [String],
      default: 'slider'
    }
  },
  data() {
    return {
      slider: null, //滚动条DOM元素
      thunk: null, //拖拽DOM元素
      per: Math.round((this.value - this.min) / this.step), //当前值
      newWidth: '',
      widthBack: null,
      disX: null,
      dragging: false
    }
  },
  computed: {
    trueMin() {
      return 0
    },
    trueMax() {
      return Math.round((this.max - this.min) / this.step)
      // 实际的的最小值从0开始，最大值公式位为 传入的最大值和最小值的差值除以步长
    },
    scale() {
      // 设置一个百分比，提供计算slider进度宽度和trunk的left值
      // 对应公式为  当前值-最小值/最大值-最小值 = slider进度width / slider总width
      return (this.per - this.trueMin) / (this.trueMax - this.trueMin)
    },
    width() {
      // process width =  slider进度width*所占百分比
      if (this.slider) {
        return this.slider.offsetWidth * this.scale + 'px'
      } else {
        return 0 + 'px'
      }
    },
    left() {
      // trunk left =  slider进度width*所占百分比 + trunk宽度/2
      if (this.slider) {
        return (
          this.slider.offsetWidth * this.scale -
          this.thunk.offsetWidth / 2 +
          'px'
        )
      } else {
        return 0 + 'px'
      }
    },
    nodeList() {
      // 存放滑块之间的离散点的位置信息以及数据
      let node = 0
      node++
      let nodeList = []
      let stepsLeft = []
      while (node < this.trueMax) {
        nodeList.push(node)
        node = node + 1
      }
      nodeList.forEach((item, i) => {
        const scale = (item - this.trueMin) / (this.trueMax - this.trueMin)
        let left = this.slider.offsetWidth * scale - this.thunk.offsetWidth / 2
        left = left + 12
        left = left + 'px'
        let value = this.min + scale * (this.max - this.min)
        if (this.name === 'amount') {
          value = this.$store.getters.moneyTransferToM(value)
        }
        stepsLeft.push({ left: left, value: value })
      })
      return stepsLeft
    }
  },
  watch: {
    value(val) {
      this.per = Math.round((this.value - this.min) / this.step)
      // 组件传入的value和组件内部的per值对应的公式为 per*step = value-min
    }
  },
  mounted() {
    this.slider = this.$refs.slider
    // 兼容pc版的鼠标事件和m版的touch事件
    // 对应给thunkformPC绑定上鼠标事件，thunkformM绑定上touch事件
    if (this.$refs.thunkformPC.offsetWidth) {
      this.thunk = this.$refs.thunkformPC
    } else {
      this.thunk = this.$refs.thunkformM
    }
  },
  methods: {
    start(e) {
      e.preventDefault()
      this.dragging = true
      var _this = this
      this.widthBack = parseInt(_this.width)
      let target
      if (e.targetTouches) {
        target = e.targetTouches[0]
        this.disX = target.clientX
      } else {
        target = e
        this.disX = target.clientX
        document.addEventListener('mousemove', function(e) {
          _this.move(e)
        })
        document.addEventListener('mouseup', function(e) {
          _this.end(e)
        })
      }
    },
    move(e) {
      e.preventDefault()
      if (this.dragging) {
        var _this = this
        // value, left, width
        // 当value变化的时候，会通过计算属性修改left，width

        // 拖拽的时候获取的新width
        let target
        if (e.targetTouches) {
          target = e.targetTouches[0]
        } else {
          target = e
        }
        this.newWidth = target.clientX - this.disX + this.widthBack
        // 拖拽的时候得到新的百分比
        var scale = this.newWidth / this.$refs.slider.offsetWidth
        _this.per = Math.ceil(
          (this.trueMax - this.trueMin) * scale + this.trueMin
        )
        _this.per = Math.max(_this.per, this.trueMin)
        _this.per = Math.min(_this.per, this.trueMax)
      }
    },
    end(e) {
      e.preventDefault()
      this.dragging = false
      this.$emit('change', this.per * this.step + this.min)
    }
  }
}
</script>
<style lang="scss" scoped>
.wrap {
  margin-bottom: 30px;
}
.clear:after {
  content: '';
  display: block;
  clear: both;
}
.slider {
  position: relative;
  margin: 20px 0;
  height: 6px;
  background: #e4e7ed;
  border-radius: 5px;
  cursor: grabbing;
  z-index: 99;
  .process {
    position: absolute;
    left: 0;
    top: 0;
    width: 112px;
    height: 6px;
    border-radius: 5px;
    background: #3462ff;
    z-index: 2;
  }
  .thunk {
    position: absolute;
    left: 100px;
    top: -11px;
    width: 48px;
    height: 36px;
  }
  .block {
    /* width:20px;height:20px;border-radius:50%;border:2px solid #409eff;background:rgba(255,255,255,1);transition:.2s all */
    width: 48px;
    height: 36px;
    border: none;
    background: url(../static/img/huakuai.png);
    background-size: cover;
    border-radius: 5px;
    z-index: 3;
  }
  .tips {
    position: absolute;
    left: -7px;
    bottom: 30px;
    min-width: 15px;
    text-align: center;
    padding: 4px 8px;
    background: #000;
    border-radius: 5px;
    height: 24px;
    color: #fff;
  }
  .tips i {
    position: absolute;
    margin-left: -5px;
    left: 50%;
    bottom: -9px;
    font-size: 16px;
    color: #000;
  }
  .block:hover {
    transform: scale(1.1);
    opacity: 0.6;
  }
}
@media screen and (min-width: 1200px) {
  .node-wrap {
    .step {
      position: absolute;
      border-radius: 50%;
      width: 6px;
      height: 6px;
      color: #fff;
    }
    .value {
      position: absolute;
      top: 15px;
      border-radius: 50%;
      color: #666;
      line-height: 36px;
    }
  }
}
@media screen and (min-width: 768px) and (max-width: 1199px) {
  .node-wrap {
    .step {
      position: absolute;
      border-radius: 50%;
      width: 6px;
      height: 6px;
      background: #fff;
    }
    .value {
      position: absolute;
      top: 15px;
      border-radius: 50%;
      color: #666;
      line-height: 36px;
    }
  }
}
@media only screen and (max-width: 767px) {
  .node-wrap {
    .step {
      position: absolute;
      border-radius: 50%;
      width: 6px;
      height: 6px;
      background: #fff;
    }
    .value {
      position: absolute;
      top: 15px;
      border-radius: 50%;
      color: #fff;
      line-height: 36px;
    }
  }
}
</style>
